/**
 * 
 */
package neptune.manager.validator;

/**
 * Rappresenta una regola per la validazione dell'oggetto passato come
 * argomento. Da notare che il metodo
 * {@link ValidatorRule#validate(Object, ValidatorResult)} e' parametrizzato, in
 * base al tipo dell'oggetto che si vuole validare.
 * 
 * @author Roberto Bifulco [RobertoBifulco.it] [info@robertoBifulco.it]
 * 
 */
public abstract class ValidatorRule<T> {

	/**
	 * Convalida l'oggetto passato come argomento. L'argomento ValidatorResult
	 * viene popolato con il risultato della convalida. Lo stesso oggetto viene
	 * anche passato come parametro di ritorno del metodo. Nel caso in cui
	 * l'oggetto ValidatorReturn sia null, viene restituito un nuovo oggetto
	 * ValidatorResult creato dal metodo.<br>
	 * <br>
	 * La generazione dell'albero di ValidatorResult e' gestita automaticamente.
	 * E' quindi sufficiente passare al metodo l'oggetto ValidatorResult
	 * adoperato come root dell'albero, a cui, questo metodo, aggiungera' gli
	 * opportuni figli.
	 * 
	 * @param <T>
	 * @param toValidate
	 * @param result
	 * @return
	 */
	public ValidatorResult validate(T toValidate, ValidatorResult result) {
		if(toValidate == null)
			return result;
		if (result == null)
			result = new ValidatorResult();
		return validationAlgorithm(toValidate, result.createChild(getName()));
	}

	/**
	 * Questo metodo astratto implementa l'effettivo algoritmo di validazione.
	 * Il parametro ValidatorResult e' quello che deve essere popolato con i
	 * risultati, poiche' e' stato appositamente per la chiamata di questo
	 * metodo.
	 * 
	 * @param toValidate
	 * @param result
	 * @return
	 */
	protected abstract ValidatorResult validationAlgorithm(T toValidate,
			ValidatorResult result);

	/**
	 * Metodo astratto che restituisce il nome di questa rule.
	 * 
	 * @return
	 */
	public abstract String getName();
}
